home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-06 / an201x.zip / INVENTRY.C < prev    next >
C/C++ Source or Header  |  1991-12-19  |  19KB  |  709 lines

  1. /*****************************************************************************
  2. * Project:  Workstation inventory
  3. * File:        INVENTRY.C
  4. * Author:    Morgan B. Adair
  5. * Date:        12/15/91
  6. *****************************************************************************/
  7.  
  8. /********** includes *********/
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <mem.h>
  13. #include <bios.h>
  14. #include <dos.h>
  15. #include <string.h>
  16. #include <nit.h>
  17. #include <niterror.h>
  18. #include <nxt.h>
  19. #include <diag.h>
  20. #include "recdecl.h"
  21. #include "btrieve.h"
  22. #include "datafile.h"
  23.  
  24. /********** defines *********/
  25.  
  26. #define PROGRAM_NAME "INVENTRY"
  27.  
  28. #define NUM_PRINTERS        0xC000
  29. #define NUM_SERIAL_PORTS    0x0E00
  30. #define NUM_FLOPPY_DRIVES    0x00C0
  31. #define MATH_COPROC        0x0002
  32. #define HAS_FLOPPIES        0x0001
  33. #define CARRY_FLAG        0x0001
  34. #define MOUSE_DRVR_MAJOR_VER    0xFF00
  35. #define MOUSE_DRVR_MINOR_VER    0x00FF
  36. #define IGNORE            0
  37. #define NOT_READY        2
  38.  
  39. /********** typedefs *********/
  40.  
  41. typedef struct SYS_DESC_TABLE {
  42.     WORD    length;
  43.     BYTE    model;
  44.     BYTE    submodel;
  45.     BYTE    BIOSrevisionLevel;
  46.     BYTE    featureFlags;
  47.     BYTE    reserved[4];
  48. } SYS_DESC_TABLE;
  49.  
  50. /********** function prototypes *********/
  51.  
  52. extern int cputype(void);
  53.  
  54. int GetNetworkData(BYTE *network, BYTE *node,
  55.            char *userName,
  56.            BYTE *IPXmajorVersion,
  57.            BYTE *IPXminorVersion,
  58.            BYTE *SPXmajorVersion,
  59.            BYTE *SPXminorVersion,
  60.            BYTE *shellMajorVersion,
  61.            BYTE *shellMinorVersion,
  62.            BYTE *shellRevisionLevel);
  63. void GetMachineModel(BYTE *machineModel, BYTE *machineSubmodel);
  64. void GetProcessorType(WORD *processorType);
  65. void GetCoprocessorType(WORD *coprocessorType);
  66. void GetConventionalMemory(int *conventionalMemoryK);
  67. void GetExtendedMemory(WORD *extendedMemoryK);
  68. void GetExpandedMemory(WORD *expandedMemoryK);
  69. int EMMInstalled(void);
  70. void GetVideoHardware(int *videoHardware, int *alternateVideoHardware);
  71. void GetDOSVersion(BYTE *DOSversionMajor, BYTE *DOSversionMinor);
  72. void GetNICType(BYTE *NICtype);
  73. void GetOtherEquipment(BYTE *numPrintersInstalled,
  74.                BYTE *numSerialPorts,
  75.                BYTE *numFloppyDrives);
  76. void GetMouse(BYTE *mouseType, WORD *mouseDriverVersion);
  77. void GetFloppyDriveTypes(BYTE numFloppyDrives, BYTE *floppyDriveType);
  78. void GetHardDisks(BYTE *numHardDrives, LONG *hardDriveSize);
  79. void DisplayType(int displayCode);
  80.  
  81. /********** global vars *********/
  82.  
  83. int    verbose = 0;
  84.  
  85. void main(int argc, char **argv)
  86. {
  87.     int            status;
  88.     int            iLoadedBtrieve = 0;
  89.     WS_INVENTORY_RECORD    inventoryRecord;
  90.     char            dbPath[80] = "\\PUBLIC\\INVENTRY.BTV";
  91.  
  92.     printf("%s: network workstation hardware inventory\n", PROGRAM_NAME);
  93.  
  94.     if (argc > 3) {
  95.         printf("Usage:\n");
  96.         printf("\t%s [-v] [path]\n", PROGRAM_NAME);
  97.         printf("\t-v     (verbose) Echo hardware description on workstation screen\n");
  98.         printf("\tpath   Path for database file\n");
  99.         printf("\t       Default path is %s\n", dbPath);
  100.     } else if (argc > 1)
  101.         while (argc > 1) {
  102.             argc--;
  103.  
  104.             if (stricmp(argv[argc], "-v") == 0)
  105.                 verbose = TRUE;
  106.  
  107.             else
  108.                 strcpy(dbPath, argv[argc]);
  109.         }
  110.  
  111.     if (!(BtrieveIsLoaded())) {
  112.         LoadBtrieve();
  113.         if (!(BtrieveIsLoaded())) {
  114.             printf("Unable to load Btrieve record manager\n");
  115.             exit(1);
  116.         }
  117.         iLoadedBtrieve = TRUE;
  118.     }
  119.  
  120.     if (!(DataFileExists(dbPath))) {
  121.         status = CreateDataFile(dbPath);
  122.         if (status) {
  123.             printf("Unable to create database file, Btrieve error code %d\n", status);
  124.             exit(1);
  125.         }
  126.     }
  127.  
  128.     status =  OpenDataFile(dbPath);
  129.     if (status) {
  130.         printf("Unable to open file %s\n", dbPath);
  131.         printf("Btrieve error code %d\n", status);
  132.         exit(1);
  133.     }
  134.  
  135.     /* zero out inventory record */
  136.     memset(&inventoryRecord, 0, sizeof(WS_INVENTORY_RECORD));
  137.  
  138.     status = GetNetworkData(inventoryRecord.network,
  139.                 inventoryRecord.node,
  140.                 inventoryRecord.userName,
  141.                 &inventoryRecord.IPXmajorVersion,
  142.                 &inventoryRecord.IPXminorVersion,
  143.                 &inventoryRecord.SPXmajorVersion,
  144.                 &inventoryRecord.SPXminorVersion,
  145.                 &inventoryRecord.shellMajorVersion,
  146.                 &inventoryRecord.shellMinorVersion,
  147.                 &inventoryRecord.shellRevisionLevel);
  148.     if (status != SUCCESSFUL)
  149.         printf("Network not loaded\n");
  150.  
  151.     GetMachineModel(&inventoryRecord.machineModel, &inventoryRecord.machineSubmodel);
  152.  
  153.     GetProcessorType(&inventoryRecord.processorType);
  154.  
  155.     GetCoprocessorType(&inventoryRecord.coprocessorType);
  156.  
  157.     GetConventionalMemory(&inventoryRecord.conventionalMemoryK);
  158.  
  159.     GetExtendedMemory(&inventoryRecord.extendedMemoryK);
  160.  
  161.     GetExpandedMemory(&inventoryRecord.expandedMemoryK);
  162.  
  163.     GetVideoHardware(&inventoryRecord.videoHardware, &inventoryRecord.alternateVideoHardware);
  164.  
  165.     GetDOSVersion(&inventoryRecord.DOSversionMajor, &inventoryRecord.DOSversionMinor);
  166.  
  167.     GetNICType(inventoryRecord.NICtype);
  168.  
  169.     GetOtherEquipment(&inventoryRecord.numPrintersInstalled,
  170.               &inventoryRecord.numSerialPorts,
  171.               &inventoryRecord.numFloppyDrives);
  172.  
  173.     GetMouse(&inventoryRecord.mouseType, &inventoryRecord.mouseDriverVersion);
  174.  
  175.     GetFloppyDriveTypes(inventoryRecord.numFloppyDrives, &inventoryRecord.floppyDriveType[0]);
  176.  
  177.     GetHardDisks(&inventoryRecord.numHardDrives, &inventoryRecord.hardDriveSize[0]);
  178.  
  179.     status = SearchItem(&inventoryRecord);
  180.     if (status == BT_SUCCESS)
  181.         status = UpdateItem(&inventoryRecord);
  182.     else
  183.         status = InsertItem(&inventoryRecord);
  184.  
  185.     if (status) {
  186.         printf("Unable to add inventory record\n");
  187.         printf("Btrieve error code %d\n", status);
  188.     }
  189.  
  190.     status = CloseDataFile();
  191.     if (status) {
  192.         printf("Unable to close inventory data file\n");
  193.         printf("Btrieve error code %d\n", status);
  194.     }
  195.  
  196.     if (iLoadedBtrieve) {
  197.         status = UnloadBtrieve();
  198.         if (status) {
  199.             printf("Unable to unload Btrieve record manager\n");
  200.             printf("Btrieve error code %d\n", status);
  201.         }
  202.     }
  203. }
  204.  
  205. int GetNetworkData(BYTE *network, BYTE *node,
  206.            char *userName,
  207.            BYTE *IPXmajorVersion,
  208.            BYTE *IPXminorVersion,
  209.            BYTE *SPXmajorVersion,
  210.            BYTE *SPXminorVersion,
  211.            BYTE *shellMajorVersion,
  212.            BYTE *shellMinorVersion,
  213.            BYTE *shellRevisionLevel)
  214. {
  215.     BeginDiagnosticStruct    networkAddress;
  216.     int            ccode;
  217.     BYTE            componentList[54];
  218.     int            component;
  219.     AllResponseData        response;
  220.     IPXSPXVersion        ipxSpxData;
  221.     WORD            connectionID;
  222.     ShellVersionStruct    shellVerData;
  223.     WORD            connectionNumber;
  224.  
  225.     /* Get network and node addresses */
  226.     /* make sure there is a network down there */ 
  227.     if (IPXInitialize() == IPX_NOT_INSTALLED)
  228.         return(~SUCCESSFUL);
  229.  
  230.     /* get network address */
  231.     IPXGetInternetworkAddress((BYTE *)&networkAddress);
  232.  
  233.     /* copy to inventory record */
  234.     memcpy(network, networkAddress.network, 4);
  235.     memcpy(node, networkAddress.node, 6);
  236.  
  237.     /* Get IPX/SPX versions */
  238.     /* Get diagnostics component list */
  239.     ccode = BeginDiagnostics(&networkAddress, &connectionID, componentList);
  240.     if (ccode != SUCCESSFUL) {
  241.         if (verbose)
  242.             printf("Unable to get IPX/SPX versions\n");
  243.     } else {
  244.         ccode = SPXInitialize(NULL, NULL, NULL, NULL);
  245.         if (ccode == SPX_NOT_INSTALLED) {
  246.             if (verbose)
  247.                 printf("SPX is not loaded\n");
  248.             return(~SUCCESSFUL);
  249.         }
  250.  
  251.         /* find the offset of the IPX/SPX component in the component list */
  252.         component = FindComponentOffset(componentList, IPX_SPX_COMPONENT);
  253.         if (component == -1) {
  254.             if (verbose)
  255.                 printf("Unable to get IPX/SPX versions\n");
  256.             return(~SUCCESSFUL);
  257.         
  258.         } else {
  259.             /* get the IPX/SPX data from the diagnostics components */
  260.             if (GetIPXSPXVersion(connectionID, component, &response, &ipxSpxData) != SUCCESSFUL) {
  261.                 if (verbose)
  262.                     printf("Unable to get IPX/SPX versions\n");
  263.                 return(~SUCCESSFUL);
  264.             } else {
  265.                 *IPXmajorVersion = ipxSpxData.IPXMajorVersion;
  266.                 *IPXminorVersion = ipxSpxData.IPXMinorVersion;
  267.                 *SPXmajorVersion = ipxSpxData.SPXMajorVersion;
  268.                 *SPXminorVersion = ipxSpxData.SPXMinorVersion;
  269.  
  270.                 if (verbose) {
  271.                     printf("IPX Version: %d.%02d\n", *IPXmajorVersion, *IPXminorVersion);
  272.                     printf("SPX Version: %d.%02d\n", *SPXmajorVersion, *SPXminorVersion);
  273.                 }
  274.             }
  275.         }
  276.  
  277.         /* Get shell version */
  278.         component = FindComponentOffset(componentList, SHELL_COMPONENT);
  279.         if (component == -1) {
  280.             if (verbose)
  281.                 printf("Unable to get shell version\n");
  282.             return(~SUCCESSFUL);
  283.  
  284.         } else {
  285.             ccode = GetShellVersionInfo(connectionID, component, &response, &shellVerData);
  286.             if (ccode != SUCCESSFUL) {
  287.                 if (verbose)
  288.                     printf("Unable to get shell version\n");
  289.                 return(~SUCCESSFUL);
  290.             } else {
  291.                 *shellMajorVersion = shellVerData.major;
  292.                 *shellMinorVersion = shellVerData.minor;
  293.                 *shellRevisionLevel = shellVerData.rev;
  294.  
  295.                 if (verbose)
  296.                     printf("Shell Version: %d.%d, Rev %c\n", *shellMajorVersion,
  297.                                          *shellMinorVersion,
  298.                                          *shellRevisionLevel+'A');
  299.             }
  300.         }
  301.     }
  302.     EndDiagnostics(connectionID);
  303.  
  304.     /* Get user name on default server */
  305.     connectionNumber = GetConnectionNumber();
  306.     ccode = GetConnectionInformation(connectionNumber, userName, (WORD *)NULL, (long *)NULL, (BYTE *)NULL);
  307.     if (verbose)
  308.         printf("User name (default server): %s\n", userName);
  309.  
  310.     if (!ccode)
  311.         return(SUCCESSFUL);
  312.     else
  313.         return(~SUCCESSFUL);
  314. }
  315.  
  316. void GetMachineModel(BYTE *machineModel, BYTE *machineSubmodel)
  317. {
  318.     SYS_DESC_TABLE far     *systemDescriptorTable;
  319.  
  320.     /* clear carry flag */
  321.     _FLAGS = _FLAGS & ~CARRY_FLAG;
  322.  
  323.     /* get system configuration: interrupt 15h, function 0Ch */
  324.     asm    mov    ax,0C000h
  325.     asm    int    15h
  326.  
  327.     if ((_AH == 0) && !(_FLAGS & CARRY_FLAG)) {
  328.         systemDescriptorTable = MK_FP(_ES, _BX);
  329.  
  330.         *machineModel = systemDescriptorTable->model;
  331.         *machineSubmodel = systemDescriptorTable->submodel;
  332.  
  333.         if (verbose) {
  334.             switch (systemDescriptorTable->model) {
  335.                 case    0x2D    :    printf("Compaq Portable\n");
  336.                             break;
  337.                 case    0x9A    :    printf("Compaq Portable Plus\n");
  338.                             break;
  339.                 case    0xF8    :    printf("IBM PS/2 Model 80\n");
  340.                             break;
  341.                 case    0xF9    :    printf("IBM PC Convertible\n");
  342.                             break;
  343.                 case    0xFA    :    printf("IBM PS/2 Model 30\n");
  344.                             break;
  345.                 case    0xFB    :    printf("IBM PC XT\n");
  346.                             break;
  347.                 case    0xFC    :    switch (systemDescriptorTable->submodel) {
  348.                                 case    0    :
  349.                                 case    1    :    printf("IBM PC/AT\n");
  350.                                             break;
  351.                                 case    2    :    printf("IBM PC/XT286\n");
  352.                                             break;
  353.                                 case    4    :    printf("IBM PS/2 Model 50\n");
  354.                                             break;
  355.                                 case    5    :    printf("IBM PS/2 Model 60\n");
  356.                                             break;
  357.                                 case    0xB    :    printf("IBM PS/1\n");
  358.                                             break;
  359.                                 default        :    printf("IBM PC/AT or PS class\n");
  360.                                             break;
  361.                             }
  362.                             break;
  363.                 case    0xFD    :    printf("IBM PCjr\n");
  364.                             break;
  365.                 case    0xFE    :    printf("IBM PC/XT, Portable PC, or Compaq DeskPro\n");
  366.                             break;
  367.                 case    0xFF    :    printf("IBM PC\n");
  368.                             break;
  369.             }
  370.         }
  371.     }
  372. }
  373.  
  374. void GetProcessorType(WORD *processorType)
  375. {
  376.     *processorType = cputype();
  377.  
  378.     if (verbose) {
  379.         switch (*processorType) {
  380.             case     0x0086    :    printf("8086 or 8088 processor\n");
  381.                         break;
  382.             case     0x0286    :    printf("80286 processor\n");
  383.                         break;
  384.             case     0x0386    :    printf("80386DX or 80386SX processor\n");
  385.                         break;
  386.             case     0x0486    :    printf("80486DX or 80486SX processor\n");
  387.                         break;
  388.             default        :    printf("Error identifying CPU\n");
  389.                         break;
  390.         }
  391.     }
  392. }
  393.  
  394. void GetCoprocessorType(WORD *coprocessorType)
  395. {
  396.     switch (_8087) {
  397.         case    0    :    *coprocessorType = 0;
  398.                     break;
  399.         case    1    :    *coprocessorType = 0x0087;
  400.                     break;
  401.         case    2    :    *coprocessorType = 0x0287;
  402.                     break;
  403.         case    3    :    *coprocessorType = 0x0387;
  404.                     break;
  405.         default        :    *coprocessorType = 0xFFFF;
  406.                     break;
  407.     }
  408.  
  409.     if (verbose) {
  410.         switch (*coprocessorType) {
  411.             case    0    :    printf("No coprocessor\n");
  412.                         break;
  413.             case    0x0087    :    printf("8087 coprocessor\n");
  414.                         break;
  415.             case    0x0287    :    printf("80287 coprocessor\n");
  416.                         break;
  417.             case    0x0387    :    printf("80387 coprocessor\n");
  418.                         break;
  419.             default        :    printf("Error getting coprocessor type: %u\n", coprocessorType);
  420.                         break;
  421.         }
  422.     }
  423. }
  424.  
  425. void GetConventionalMemory(int *conventionalMemoryK)
  426. {
  427.     *conventionalMemoryK = biosmemory();
  428.  
  429.     if (verbose)
  430.         printf("%dK base memory\n", *conventionalMemoryK);
  431. }
  432.  
  433. void GetExtendedMemory(WORD *extendedMemoryK)
  434. {
  435.     int far (*himemEntry)();    /* entry point of HIMEM.SYS driver */
  436.  
  437.     /* see if HIMEM.SYS is installed */
  438.     asm    mov    ax,4300h
  439.     asm    int    2Fh
  440.  
  441.     if (_AL == 0x80) {
  442.  
  443.         /* HIMEM.SYS installed.  Get entry point of himem driver */
  444.         asm    mov    ax,4310h
  445.         asm    int    2fh
  446.  
  447.         himemEntry = MK_FP(_ES, _BX);
  448.  
  449.         /* call himem driver function 8: get extended memory size */
  450.         asm    mov    ah,08h
  451.  
  452.         himemEntry();
  453.  
  454.         *extendedMemoryK = _DX;
  455.  
  456.     } else {
  457.         /* HIMEM.SYS is not installed, use BIOS function to get extended memory */
  458.         /* clear carry flag */
  459.         _FLAGS = _FLAGS & ~CARRY_FLAG;
  460.  
  461.         /* get extended memory size: interrupt 15h, function 88h */
  462.         asm    mov    ah,88h
  463.         asm    int    15h
  464.  
  465.         if ((_FLAGS & CARRY_FLAG) != 0)
  466.             *extendedMemoryK = 0;
  467.         else
  468.             *extendedMemoryK = _AX;
  469.     }
  470.     if (verbose)
  471.         printf("%dK extended memory\n", *extendedMemoryK);
  472. }
  473.  
  474. void GetExpandedMemory(WORD *expandedMemoryK)
  475. {
  476.     if (EMMInstalled()) {
  477.         /* get expanded memory page count:
  478.            interrupt 67h, function 42h */
  479.         asm    mov    ah,42h
  480.         asm    int    67h
  481.  
  482.         if (_AH == 0)
  483.             *expandedMemoryK = _DX * 16;
  484.     }
  485.         if (verbose)
  486.             printf("%dK expanded memory\n", *expandedMemoryK);
  487. }
  488.  
  489. int EMMInstalled(void)
  490. {
  491.     char far    *deviceName;
  492.  
  493.     /* get segment of EMM device driver by calling
  494.        get interrupt vector: interrupt 21h, function 35h */
  495.     asm    mov    al,67h
  496.     asm    mov    ah,35h
  497.     asm    int    21h
  498.  
  499.     deviceName = MK_FP(_ES, 10);    /* address of character device driver name */
  500.  
  501.     /* see if the name of the EMM device driver is where it should be when driver is loaded */
  502.     if (_fmemcmp("EMMXXXX0", deviceName, 8))
  503.         return(FALSE);
  504.     else
  505.         return(TRUE);    /* if all characters matched, EMM is present */
  506. }
  507.  
  508. void GetVideoHardware(int *videoHardware, int *alternateVideoHardware)
  509. {
  510.     /* read display codes: interrupt 10h, function 1Ah, subfunction 0 */
  511.     asm    mov    ax,1A00h
  512.     asm    int    10h
  513.  
  514.     if (_AL != 0x1A) {
  515.         if (verbose)
  516.             printf("Unable to identify graphics hardware\n");
  517.  
  518.     } else {
  519.         *videoHardware = _BL;
  520.         *alternateVideoHardware = _BH;
  521.  
  522.         if (verbose) {
  523.             DisplayType(*videoHardware);
  524.  
  525.             /* if there is an alternate display, find out what type it is */
  526.             if (*alternateVideoHardware) {
  527.                 printf("Alternate display: ");
  528.                 DisplayType(*alternateVideoHardware);
  529.             }
  530.         }
  531.     }
  532. }
  533.  
  534. void GetDOSVersion(BYTE *DOSversionMajor, BYTE *DOSversionMinor)
  535. {
  536.     *DOSversionMajor = _osmajor;
  537.     *DOSversionMinor = _osminor;
  538.  
  539.     if (verbose)
  540.         printf("DOS version %d.%02d\n", _osmajor, _osminor);
  541. }
  542.  
  543. void GetNICType(BYTE *NICtype)
  544. {
  545.     BeginDiagnosticStruct        networkAddress;
  546.     int                ccode;
  547.     BYTE                componentList[54];
  548.     int                component;
  549.     AllResponseData            response;
  550.     DriverConfigurationStruct    driverData;
  551.     WORD                connectionID;
  552.  
  553.     /* do network diagnostics, same as we did for IPX/SPX/shell */
  554.     IPXGetInternetworkAddress((BYTE *)&networkAddress);
  555.  
  556.     ccode = BeginDiagnostics(&networkAddress, &connectionID, componentList);
  557.     if ((ccode != SUCCESSFUL) && (verbose)) {
  558.         printf("Unable to get network card type\n");
  559.     } else {
  560.         component = FindComponentOffset(componentList, SHELL_DRIVER_COMPONENT);
  561.         if ((component == -1) && (verbose)) {
  562.             printf("Unable to get network card type\n");
  563.         } else {
  564.             if ((GetShellDriverConfiguration(connectionID, component, &response, &driverData) != SUCCESSFUL) &&
  565.                 (verbose)) {
  566.                 printf("Unable to get network card type\n");
  567.             } else {
  568.                 strcpy((char *)NICtype, (char *)driverData.LANDescription);
  569.                 if (verbose)
  570.                     printf("%s\n", NICtype);
  571.             }
  572.         }
  573.     }
  574.     EndDiagnostics(connectionID);
  575. }
  576.  
  577. void GetOtherEquipment(BYTE *numPrintersInstalled,
  578.                BYTE *numSerialPorts,
  579.                BYTE *numFloppyDrives)
  580. {
  581.     int    equipFlags;
  582.  
  583.     equipFlags = biosequip();
  584.  
  585.     if (equipFlags & HAS_FLOPPIES)
  586.         *numFloppyDrives = ((equipFlags & NUM_FLOPPY_DRIVES) >> 6) + 1;
  587.     *numPrintersInstalled = (equipFlags & NUM_PRINTERS) >> 14;
  588.     *numSerialPorts = (equipFlags & NUM_SERIAL_PORTS) >> 9;
  589.  
  590.     if (verbose) {
  591.         printf("%d floppy drives\n", *numFloppyDrives);
  592.         printf("%d printers installed\n", *numPrintersInstalled);
  593.         printf("%d serial ports\n", *numSerialPorts);
  594.     }
  595. }
  596.  
  597. void GetMouse(BYTE *mouseType, WORD *mouseDriverVersion)
  598. {
  599.     /* mouse status: interrupt 33h, function 0 */
  600.     asm    mov    ax,0h
  601.     asm    int    33h
  602.  
  603.     if (_AX) {
  604.         /* mouse installed */
  605.         /* get mouse driver version and mouse type:
  606.            interrupt 33h, function 24h */
  607.         asm    mov    ax,24h
  608.         asm    int    33h
  609.  
  610.         *mouseType = _CH;
  611.         *mouseDriverVersion = _BX;
  612.  
  613.         if (verbose) {
  614.             printf("Mouse driver version: %d.%02d\n",
  615.                 (*mouseDriverVersion & MOUSE_DRVR_MAJOR_VER) >> 8,
  616.                  *mouseDriverVersion & MOUSE_DRVR_MINOR_VER);
  617.  
  618.             switch (*mouseType) {
  619.                 case 1    :    printf("Bus mouse\n");
  620.                         break;
  621.                 case 2    :    printf("Serial mouse\n");
  622.                         break;
  623.                 case 3    :    printf("InPort mouse\n");
  624.                         break;
  625.                 case 4    :    printf("PS/2 mouse\n");
  626.                         break;
  627.                 case 5    :    printf("Hewlet-Packard mouse\n");
  628.                         break;
  629.                 default    :    printf("Unknown mouse type\n");
  630.                         break;
  631.             }
  632.         }
  633.     }
  634. }
  635.  
  636. void GetFloppyDriveTypes(BYTE numFloppyDrives, BYTE *floppyDriveType)
  637. {
  638.     BYTE    i;
  639.     BYTE    driveTypeTemp;
  640.  
  641.     for (i=0; i<numFloppyDrives; i++) {
  642.         /* read drive parameters: interrupt 13h, function 8 */
  643.         asm    mov    ah,08h
  644.         asm    mov    dl,i
  645.         asm    int    13h
  646.  
  647.         driveTypeTemp = _BL;        /* use temp variable, because
  648.                            assignment directly to the
  649.                            array changes _BL */
  650.         floppyDriveType[i] = driveTypeTemp;
  651.  
  652.         if (verbose) {
  653.             printf("Floppy drive %d: ", i);
  654.             switch (floppyDriveType[i]) {
  655.                 case    1    :    printf("360KB\n");
  656.                             break;
  657.                 case    2    :    printf("1.2MB\n");
  658.                             break;
  659.                 case    3    :    printf("720KB\n");
  660.                             break;
  661.                 case    4    :    printf("1.44MB\n");
  662.                             break;
  663.                 default        :    printf("unable to identify type\n");
  664.                             break;
  665.             }
  666.         }
  667.     }
  668. }
  669.  
  670. void GetHardDisks(BYTE *numHardDrives, LONG *hardDriveSize)
  671. {
  672.     BYTE        driveNumber;
  673.     LONG        freeBytes, bytesPerCluster;
  674.     struct dfree    diskFreeInfo;
  675.  
  676.     driveNumber = 3;
  677.         /* assume drives 1 & 2 (A: & B:), if they
  678.            exist, are mapped to floppy drives */
  679.     while ((driveNumber <= 26) && (*numHardDrives <= MAX_HARD_DRIVES)) {
  680.  
  681.         /* clear carry flag */
  682.         _FLAGS = _FLAGS & ~CARRY_FLAG;
  683.  
  684.         /* skip if network drive */
  685.         asm    mov    ah,44h
  686.         asm    mov    al,09h
  687.         asm    mov    bl,driveNumber
  688.         asm    int    21h
  689.  
  690.         if ((!(_FLAGS & CARRY_FLAG)) &&        /* carry flag set on errror */
  691.             (!(_DX & 0x1000))) {        /* bit 12 of dx is set if remote */
  692.  
  693.             getdfree(driveNumber, &diskFreeInfo);
  694.             if (diskFreeInfo.df_sclus != 0xFFFF) {
  695.                 bytesPerCluster = (LONG)diskFreeInfo.df_sclus * (LONG)diskFreeInfo.df_bsec;
  696.                 hardDriveSize[*numHardDrives] = (LONG)diskFreeInfo.df_total * bytesPerCluster;
  697.                 freeBytes = (LONG)diskFreeInfo.df_avail * bytesPerCluster;
  698.  
  699.                 if (verbose)
  700.                     printf("Drive %c: %ld bytes free out of %ld bytes\n",
  701.                         driveNumber+'A'-1, freeBytes, hardDriveSize[*numHardDrives]);
  702.  
  703.                 *numHardDrives = *numHardDrives+1;
  704.             }
  705.         }
  706.         driveNumber++;
  707.     }
  708. }
  709.